#include "apps.h"

#define RETRY_INIT_DELAY 2000
#define RUN_DELAY 1000

void configureSensor();
void printResult(String text, OPT3001 result);

bool opt3001_init()
{
	opt3001.begin(OPT3001_ADDRESS);
	uint16_t id = opt3001.readManufacturerID();
	log_i("OPT3001 Manufacturer ID:0X%04X", id);
	if (id == 0)
	{
		return false;
	}
	log_i("OPT3001 Device ID:0X%04X", opt3001.readDeviceID());

	configureSensor();
	printResult("High-Limit", opt3001.readHighLimit());
	printResult("Low-Limit", opt3001.readLowLimit());
	return true;
}
OPT3001 result;
void opt3001_loop()
{
	static uint32_t last = 0;
	static int state = 0;
	static uint32_t mark = 0;

	if (millis() - last < 100)
	{
		return;
	}
	last = millis();
	switch (state)
	{
	case 0:
		if (opt3001_init() == true)
		{
			log_i("OPT3001 initialization successful");
			state = 2;
		}
		else
		{
			log_e("OPT3001 initialization error: 1");
			state = 1;
		}
		mark = millis();

		break;
	case 1:
		if (millis() - mark < RETRY_INIT_DELAY)
		{
			break;
		}
		else
		{
			state = 0;
		}
		break;
	case 2:
		result = opt3001.readResult();
		if (result.error != NO_ERROR)
		{
			state = 0;
			log_e("error: %d", result.error);
		}
		else
		{
			state = 3;
			printResult("OPT3001", result);
		}
		mark = millis();
		break;
	case 3:
		if (millis() - mark < RUN_DELAY) // 10 * 100ms = 1s
		{
			break;
		}
		else
		{
			state = 2;
		}
		break;
	default:
		state = 0;
		break;
	}
}

void configureSensor()
{
	OPT3001_Config newConfig;

	newConfig.RangeNumber = B1100;
	newConfig.ConvertionTime = B0;
	newConfig.Latch = B1;
	newConfig.ModeOfConversionOperation = B11;

	OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
	if (errorConfig != NO_ERROR)
	{
		log_e("Err:%d", errorConfig);
	}
	else
	{
		OPT3001_Config sensorConfig = opt3001.readConfig();
		// log_i("OPT3001 Current Config:");
		// log_i("------------------------------");
		// log_i("Conversion ready (R):0X%02X", sensorConfig.ConversionReady);
		// log_i("Conversion time (R/W):0X%02X", sensorConfig.ConvertionTime);
		// log_i("Fault count field (R/W):0X%02X", sensorConfig.FaultCount);
		// log_i("Flag high field (R-only):0X%02X", sensorConfig.FlagHigh);
		// log_i("Flag low field (R-only):0X%02X", sensorConfig.FlagLow);
		// log_i("Latch field (R/W):0X%02X", sensorConfig.Latch);
		// log_i("Mask exponent field (R/W):0X%02X", sensorConfig.MaskExponent);
		// log_i("Mode of conversion operation (R/W):0X%02X", sensorConfig.ModeOfConversionOperation);
		// log_i("Polarity field (R/W):0X%02X", sensorConfig.Polarity);
		// log_i("Overflow flag (R-only):0X%02X", sensorConfig.OverflowFlag);
		// log_i("Range number (R/W):0X%02X", sensorConfig.RangeNumber);
		// log_i("------------------------------");
	}
}

void printResult(String text, OPT3001 result)
{
	if (result.error == NO_ERROR)
	{
		log_i("%s:%0.3flux", text.c_str(), result.lux);
	}
	else
	{
		log_e("Err:%d", result.error);
	}
}
